package com.xl.core.util.zip;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import com.xl.core.util.StringUtil;

/**
 * ZIP格式压缩文件夹
 * 
 * @author 梁华
 * 
 */
public final class ZipUtil {

	/**
	 * 压缩文件(.zip)的函数
	 * 
	 * @param zipDirectory
	 *            (需要)压缩的文件夹路径
	 * @param zipPath
	 *            文件压缩后放置的路径
	 * @return 成功：true 否则false
	 */
	public static boolean doZip(String zipDirectory, String zipPath) {

		// 如果路径为空，则返回false
		if (StringUtil.isEmpty(zipDirectory) || StringUtil.isEmpty(zipPath)) {
			return false;
		}

		// 需要压缩文件夹
		File zipDir = new File(zipDirectory);

		// 压缩的文件
		File zipFile = new File(zipPath);
		// 存在压缩文件，删除后重新压缩
		if (zipFile.exists()) {
			zipFile.delete();
		}

		try {
			ZipOutputStream zipOut = new ZipOutputStream(
					new BufferedOutputStream(new FileOutputStream(zipFile)));

			// 压缩文件
			handleDir(zipDir, zipDir.getParent().length() + 1, zipOut);

			zipOut.close();

			return true;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 由doZip调用,递归完成目录文件读取
	 * 
	 * @param dir
	 *            (需要)压缩的文件夹(File 类型)
	 * @param len
	 *            一个参数(记录压缩文件夹的parent路径的长度)
	 * @param zipOut
	 *            需要压缩进的压缩文件
	 * @throws IOException
	 *             如果出错,会抛出IOE异常
	 */
	private static void handleDir(File dir, int len, ZipOutputStream zipOut)
			throws IOException {

		int readedBytes = 0;
		byte[] buf = new byte[1024];

		FileInputStream fileIn = null;
		File[] files = dir.listFiles();

		if (files != null) {
			if (files.length > 0) { // 如果目录不为空,则分别处理目录和文件.
				for (File fileName : files) {

					if (fileName.isDirectory()) {
						handleDir(fileName, len, zipOut);

					} else {
						fileIn = new FileInputStream(fileName);

						zipOut.putNextEntry(new ZipEntry(fileName.getPath()
								.substring(len).replaceAll("\\\\", "/")));

						while ((readedBytes = fileIn.read(buf)) > 0) {
							zipOut.write(buf, 0, readedBytes);
						}
						zipOut.closeEntry();
					}
				}
			} else { // 如果目录为空,则单独创建之.
				zipOut.putNextEntry(new ZipEntry(dir.getPath().substring(len)
						+ "/"));
				zipOut.closeEntry();
			}
		} else {// 如果是一个单独的文件
			fileIn = new FileInputStream(dir);

			zipOut.putNextEntry(new ZipEntry(dir.getPath().substring(len)));

			while ((readedBytes = fileIn.read(buf)) > 0) {
				zipOut.write(buf, 0, readedBytes);
			}
			zipOut.closeEntry();
		}
	}

	public static void main(String[] args) {
		doZip("E:\\图片\\数据库备份", "E:\\test.zip");
	}
}
